package ${projectDomain}.adapter.validate;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.unswift.annotation.api.Api;
import com.unswift.annotation.api.ApiField;
import com.unswift.annotation.api.ApiMethod;
import ${projectDomain}.adapter.BaseSearchAdapter;
import ${projectDomain}.cache.ICacheAdapter;
import ${projectDomain}.core.entity.TokenUser;
import ${projectDomain}.language.fovasala.FovasalaCode;
import ${projectDomain}.language.fovasala.FovasalaCodeParse;
import ${projectDomain}.language.fovasala.FovasalaSymbolEnum;
import ${projectDomain}.pojo.Pojo;
import ${projectDomain}.pojo.bo.validate.ValidateEntity;
import ${projectDomain}.pojo.cho.system.form.validate.SystemFormValidateCho;
import ${projectDomain}.utils.ServletUtils;
import com.unswift.utils.ClassUtils;
import com.unswift.utils.ExceptionUtils;
import com.unswift.utils.NumberUtils;
import com.unswift.utils.ObjectUtils;

@Component
@Api(value="数据验证类，此Service主要是对表单及实体进行数据校验", author="unswift", date="2023-04-16", version="1.0.0")
public class ValidateAdapter implements IValidateAdapter{

	@ApiField("日志对象")
	private final Logger logger=LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	private ICacheAdapter cacheAdapter;
	@Autowired
	private FovasalaCodeParse fovasalaCodeParse;
	
	@ApiField("验证本地线程对象（可在验证之前设置参数，在验证时可使用）")
	private ThreadLocal<Map<String, Object>> attributeLocal=new InheritableThreadLocal<Map<String, Object>>(){
		protected Map<String, Object> initialValue() {//初始化本线程变量
			return new HashMap<String, Object>();
		};
	};
	
	@Override
	@ApiMethod(value="验证单个实体", params={@ApiField("所属模块"), @ApiField("具体的操作"), @ApiField("需要验证的实体对象"), @ApiField("当前用户"), @ApiField("模块的公共组件")})
	public <E extends Pojo> void validate(String module, String operator, E entity, TokenUser user, BaseSearchAdapter moduleComponent) {
		ValidateEntity<E> validateEntity=new ValidateEntity<E>();
		validateEntity.setEntity(entity);
		validateEntity.setRequest(ServletUtils.getRequest());
		validateEntity.setResponse(ServletUtils.getResponse());
		validateEntity.setUser(user);
		validateEntity.setConfig(cacheAdapter.findFormValidateConfigMap());
		validateEntity.addAttribute("v", new V());
		validateEntity.addAttribute("db", moduleComponent);
		validateEntity.addAttribute("cache", cacheAdapter);
		validateEntity.addAttributes(attributeLocal.get());
		List<SystemFormValidateCho> validateList=cacheAdapter.findFormValidateList(module, operator);
		validate(validateEntity, validateList, new HashMap<Integer, Map<String, Object>>(), new Stack<KeywordBranch>());
	}

	@Override
	@ApiMethod(value="验证实体列表", params={@ApiField("所属模块"), @ApiField("具体的操作"), @ApiField("需要验证的实体列表对象"), @ApiField("当前用户"), @ApiField("模块的公共组件")})
	public <E extends Pojo> void validate(String module, String operator, List<E> entityList, TokenUser user, BaseSearchAdapter moduleComponent) {
		ValidateEntity<E> validateEntity=new ValidateEntity<E>();
		validateEntity.setRequest(ServletUtils.getRequest());
		validateEntity.setResponse(ServletUtils.getResponse());
		validateEntity.setUser(user);
		validateEntity.setConfig(cacheAdapter.findFormValidateConfigMap());
		validateEntity.addAttribute("v", new V());
		validateEntity.addAttribute("db", moduleComponent);
		validateEntity.addAttribute("cache", cacheAdapter);
		validateEntity.addAttributes(attributeLocal.get());
		List<SystemFormValidateCho> validateList=cacheAdapter.findFormValidateList(module, operator);
		if(ObjectUtils.isNotEmpty(entityList)){
			for (E entity : entityList) {
				validateEntity.setEntity(entity);
				validate(validateEntity, validateList, new HashMap<Integer, Map<String, Object>>(), new Stack<KeywordBranch>());
			}
		}
	}
	
	@Override
	@ApiMethod(value="识别实体中的各属性是否为空", params={@ApiField("实体对象")}, returns=@ApiField("是否为空，true:为空，false:不为空"))
	public <E extends Pojo> boolean entityFieldEmpty(E entity) {
		if(ObjectUtils.isEmpty(entity)){
			return true;
		}
		List<Field> fieldList = ClassUtils.getFieldList(entity.getClass());
		for (Field field : fieldList) {
			if(ObjectUtils.isNotEmpty(ClassUtils.get(entity, field))){
				return false;
			}
		}
		return true;
	}
	
	@ApiMethod(value="根据规则及封装后的实体进行验证", params={@ApiField("封装后的实体"), @ApiField("验证规则列表"), @ApiField("变量map"), @ApiField("压入堆栈的括号对象")})
	private void validate(ValidateEntity<?> validateEntity, List<SystemFormValidateCho> validateRuleList, Map<Integer, Map<String, Object>> varMap, Stack<KeywordBranch> branchStack){
		if(ObjectUtils.isNotEmpty(validateRuleList)){
			KeywordBranch branch;
			List<KeywordBranch> foreachBranchStack=new ArrayList<KeywordBranch>();
			int level;
			for (SystemFormValidateCho validateRule : validateRuleList) {
				ExceptionUtils.empty(validateRule.getKeyword(), "field.empty", String.format("验证规则类型，发生在行次：%s", validateRule.getCodeLine()));
				level=branchStack.size();
				if(KeywordEnum.KEYWORD_IF.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					if(handleTrueFalse(validateRule.getCode(), validateEntity, varMap, level, validateRule.getCodeLine())){
						tipsMessage(validateEntity, varMap, validateRule.getCodeLine(), level, validateRule);
						branchStack.push(new KeywordBranch(KeywordEnum.KEYWORD_IF.getKeyword(), level , true));
					}else{
						branchStack.push(new KeywordBranch(KeywordEnum.KEYWORD_IF.getKeyword(), level , false));
					}
				}else if(KeywordEnum.KEYWORD_ELSE_IF.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					ExceptionUtils.empty(branchStack, "form.validate.syntax.error", String.format("无法确定前置语句‘if’，发生在行次：%s", validateRule.getCodeLine()));
					branch = branchStack.peek();
					ExceptionUtils.notEquals(branch.getKeyword(), KeywordEnum.KEYWORD_IF.getKeyword(), "form.validate.syntax.error", String.format("无法确定前置语句‘if’，发生在行次：%s", validateRule.getCodeLine()));//当前语句必须时if
					if(!branch.getFirstResult()){//当前if语句如果条件为假，则执行elseif表达式
						if(handleTrueFalse(validateRule.getCode(), validateEntity, varMap, level, validateRule.getCodeLine())){
							tipsMessage(validateEntity, varMap, validateRule.getCodeLine(), level, validateRule);
							branch.setLastResult(true, true);
						}
					}else {
						branch.setLastResult(false, true);
					}
				}else if(KeywordEnum.KEYWORD_END_IF.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					ExceptionUtils.empty(branchStack, "form.validate.syntax.error", String.format("无法确定前置语句‘if’，发生在行次：%s", validateRule.getCodeLine()));
					branch = branchStack.pop();
					ExceptionUtils.notEquals(branch.getKeyword(), KeywordEnum.KEYWORD_IF.getKeyword(), "form.validate.syntax.error", String.format("‘end if’应以‘if’开始，但找到：%s，发生在行次：%s", branch.getKeyword(), validateRule.getCodeLine()));//当前语句必须时if
				}else if(KeywordEnum.KEYWORD_CASE.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					branchStack.push(new KeywordBranch(KeywordEnum.KEYWORD_CASE.getKeyword(), level , false));
				}else if(KeywordEnum.KEYWORD_WHEN_THEN.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					ExceptionUtils.empty(branchStack, "form.validate.syntax.error", String.format("无法确定前置语句‘case’，发生在行次：%s", validateRule.getCodeLine()));
					branch = branchStack.peek();
					ExceptionUtils.notEquals(branch.getKeyword(), KeywordEnum.KEYWORD_CASE.getKeyword(), "form.validate.syntax.error", String.format("无法确定前置语句‘case’，发生在行次：%s", validateRule.getCodeLine()));//当前语句必须时if
					if(!branch.getFirstResult()){//当前case语句如果条件为假，则执行when then表达式
						if(handleTrueFalse(validateRule.getCode(), validateEntity, varMap, level, validateRule.getCodeLine())){
							tipsMessage(validateEntity, varMap, validateRule.getCodeLine(), level, validateRule);
							branch.setLastResult(true, true);
						}
					}else {
						branch.setLastResult(false, true);
					}
				}else if(KeywordEnum.KEYWORD_END_CASE.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					ExceptionUtils.empty(branchStack, "form.validate.syntax.error", String.format("无法确定前置语句‘case’，发生在行次：%s", validateRule.getCodeLine()));
					branch = branchStack.pop();
					ExceptionUtils.notEquals(branch.getKeyword(), KeywordEnum.KEYWORD_CASE.getKeyword(), "form.validate.syntax.error", String.format("‘end case’应以‘case’开始，但找到：%s，发生在行次：%s", branch.getKeyword(), validateRule.getCodeLine()));//当前语句必须时case
				}else if(KeywordEnum.KEYWORD_ELSE.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					ExceptionUtils.empty(branchStack, "form.validate.syntax.error", String.format("无法确定前置语句‘if’或‘case’，发生在行次：%s", validateRule.getCodeLine()));
					branch=branchStack.peek();
					if(branch.getKeyword().equals(KeywordEnum.KEYWORD_IF.getKeyword())){//if
						if(!branch.getFirstResult()){//当前if语句如果条件为假，则执行else表达式块
							branch.setLastResult(true, true);;
						}else {
							branch.setLastResult(false, true);
						}
					}else if(branch.getKeyword().equals(KeywordEnum.KEYWORD_CASE.getKeyword())){//case
						if(!branch.getFirstResult()){//当前if语句如果条件为假，则执行else表达式块
							branch.setLastResult(true, true);;
						}else {
							branch.setLastResult(false, true);
						}
					}else{
						throw ExceptionUtils.message("form.validate.syntax.error", String.format("无法确定前置语句‘if’或‘case’，发生在行次：%s", validateRule.getCodeLine()));//当前语句必须时if
					}
				}else if(KeywordEnum.KEYWORD_FOREACH.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					branch=new KeywordBranch(KeywordEnum.KEYWORD_FOREACH.getKeyword(), level , false, new ArrayList<SystemFormValidateCho>());
					branchStack.push(branch);
					foreachBranchStack.add(branch);
					setVar(validateRule.getCode(), validateEntity, varMap, KeywordEnum.KEYWORD_FOREACH, level+1, validateRule.getCodeLine());
					if(varMap.get(level+1).get("foreachLength").equals(0)){
						branch.setLastResult(false, true);
					}else{
						branch.setLastResult(true, true);
					}
				}else if(KeywordEnum.KEYWORD_CONTINUE.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					ExceptionUtils.empty(branchStack, "form.validate.syntax.error", String.format("无法确定前置语句‘foreach’，发生在行次：%s", validateRule.getCodeLine()));
					int length=branchStack.size();
					for (int i = length-1; i >=0; i--) {
						branch=branchStack.get(i);
						if(branch.getKeyword().equals(KeywordEnum.KEYWORD_FOREACH.getKeyword())){
							branch.setLastResult(false, false);
							break;
						}else{
							branch.setLastResult(false, true);
						}
					}
				}else if(KeywordEnum.KEYWORD_BREAK.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					ExceptionUtils.empty(branchStack, "form.validate.syntax.error", String.format("无法确定前置语句‘foreach’，发生在行次：%s", validateRule.getCodeLine()));
					int length=branchStack.size();
					for (int i = length-1; i >=0; i--) {
						branch=branchStack.get(i);
						if(branch.getKeyword().equals(KeywordEnum.KEYWORD_FOREACH.getKeyword())){
							branch.setLastResult(false, false);
							branch.setFirstResult(false);//结束for循环
							break;
						}else{
							branch.setLastResult(false, true);
						}
					}
				}else if(KeywordEnum.KEYWORD_END_FOREACH.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					ExceptionUtils.empty(branchStack, "form.validate.syntax.error", String.format("无法确定前置语句‘foreach’，发生在行次：%s", validateRule.getCodeLine()));
					branch=branchStack.peek();
					ExceptionUtils.notEquals(branch.getKeyword(), KeywordEnum.KEYWORD_FOREACH.getKeyword(), "form.validate.syntax.error", String.format("‘end foreach’应以‘foreach’开始，但找到：%s，发生在行次：%s", branch.getKeyword(), validateRule.getCodeLine()));//当前语句必须时case
					if(branch.getFirstResult()){
						int length=(int)varMap.get(level).get("foreachLength");
						String foreachIndexKey = varMap.get(level).get("foreachVar")+"Index";
						int first=(int)varMap.get(level).get(foreachIndexKey);
						for (int i = first+1; i < length; i++) {
							varMap.get(level).put(foreachIndexKey, i);
							validate(validateEntity, branch.getCodeBodyList(), varMap, branchStack);
						}
					}
					branchStack.pop();
				}else if(KeywordEnum.KEYWORD_VAR.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					boolean isSetVar=true;
					if(ObjectUtils.isNotEmpty(branchStack)){
						branch=branchStack.peek();
						if(!branch.getLastResult()){
							isSetVar=false;
						}
					}
					if(isSetVar){
						setVar(validateRule.getCode(), validateEntity, varMap, KeywordEnum.KEYWORD_VAR, level, validateRule.getCodeLine());
					}
				}else if(KeywordEnum.KEYWORD_VALUE.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					boolean isSetVar=true;
					if(ObjectUtils.isNotEmpty(branchStack)){
						branch=branchStack.peek();
						if(!branch.getLastResult()){
							isSetVar=false;
						}
					}
					if(isSetVar){
						setVar(validateRule.getCode(), validateEntity, varMap, KeywordEnum.KEYWORD_VAR, level, validateRule.getCodeLine());
					}
				}else if(KeywordEnum.KEYWORD_TIPS.getKeyword().equalsIgnoreCase(validateRule.getKeyword())){
					boolean isExecuteTips=true;
					if(ObjectUtils.isNotEmpty(branchStack)){
						branch=branchStack.peek();
						if(!branch.getLastResult()){
							isExecuteTips=false;
						}
					}
					if(isExecuteTips){
						if(handleTrueFalse(validateRule.getCode(), validateEntity, varMap, level, validateRule.getCodeLine())){
							tipsMessage(validateEntity, varMap, validateRule.getCodeLine(), level, validateRule);
						}
					}
				}
				if(ObjectUtils.isNotEmpty(foreachBranchStack)){
					int size = foreachBranchStack.size()-1;
					for (int i = size; i >=0; i--) {
						if((KeywordEnum.KEYWORD_FOREACH.getKeyword().equalsIgnoreCase(validateRule.getKeyword()) 
								|| KeywordEnum.KEYWORD_END_FOREACH.getKeyword().equalsIgnoreCase(validateRule.getKeyword())) && i==size){
							continue;
						}
						foreachBranchStack.get(i).addCodeBody(validateRule);
					}
				}
			}
		}
	}

	private void tipsMessage(ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int codeRow,
			int level, SystemFormValidateCho validateRule) {
		if(ObjectUtils.isNotEmpty(validateRule.getMessage())){
			Object[] args=null;
			if(ObjectUtils.isNotEmpty(validateRule.getMessageArgs())){
				String[] argsKeys=validateRule.getMessageArgs().split("\\,");
				int length=argsKeys.length;
				args=new Object[length];
				for (int i = 0; i < length; i++) {
					args[i]=getValueByValidatePath(argsKeys[i], null, validateEntity, varMap, level, validateRule.getMessageArgs(), codeRow);
				}
			}
			logger.error("验证失败，message："+validateRule.getMessage()+"，行次："+codeRow);
			throw ExceptionUtils.message(validateRule.getMessage(), args);
		}
	}
	
	@ApiMethod(value="处理真假表达式", params={@ApiField("真假表达式"), @ApiField("表单验证对象"), @ApiField("临时变量Map"), @ApiField("代码层级"), @ApiField("代码行")})
	private boolean handleTrueFalse(String expression, ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, int codeRow){
		ExceptionUtils.empty(expression, "field.empty", String.format("表单验证代码，发生在行次：%s", codeRow));
		ExceptionUtils.falseException(expression.matches("^[!]?[a-zA-Z0-9_.\\(\\)'\"\\+\\-\\*\\/,\\[\\]\\|]+([=][=]?[a-zA-Z0-9_.\\(\\)'\"\\+\\-\\*\\/,\\[\\]\\|]+)?$"), "form.validate.syntax.error", String.format("表达式必须符合aaa=[=]bbb或者aaa.bbb(bbb为boolean值)，规范，发生在行次：%s，代码：%s", codeRow, expression));
		List<FovasalaCode> fovasalaCodeList=fovasalaCodeParse.parse(expression);
		
		firstCalcAddAdd(validateEntity, varMap, level, codeRow, expression, fovasalaCodeList);//++
		firstCalcSubSub(validateEntity, varMap, level, codeRow, expression, fovasalaCodeList);//--
		firstCalcDivide(validateEntity, varMap, level, codeRow, expression, fovasalaCodeList);//先算除法
		secondlyCalcMultiply(validateEntity, varMap, level, codeRow, expression, fovasalaCodeList);//再算乘法
		secondlyCalcAddSub(validateEntity, varMap, level, codeRow, expression, fovasalaCodeList);//再算加、减法
		joinBracketFunction(validateEntity, varMap, level, codeRow, expression, fovasalaCodeList);//把函数拼接起来
		firstCalcBeNot(validateEntity, varMap, level, codeRow, expression, fovasalaCodeList);//再算非
		
		if(fovasalaCodeList.stream().filter(f -> ObjectUtils.isNotEmpty(f.getSymbol()) && 
				ObjectUtils.containsOnce(f.getSymbol().getSymbol(), FovasalaSymbolEnum.EQUAL.getSymbol(), FovasalaSymbolEnum.NOT_EQUAL.getSymbol(), 
						FovasalaSymbolEnum.GT.getSymbol(), FovasalaSymbolEnum.GTE.getSymbol(),
						FovasalaSymbolEnum.LT.getSymbol(), FovasalaSymbolEnum.LTE.getSymbol()
		)).findAny().isPresent()){//aaa=bbb
			FovasalaCode firstCode=fovasalaCodeList.get(0);
			ExceptionUtils.trueException(fovasalaCodeList.size()!=3, "form.validate.syntax.error", String.format("无法进行表达式比较，发生在行次：%s，代码：%s", codeRow, expression));
			Object result1,result2;
			firstCode=fovasalaCodeList.get(0);
			if(FovasalaSymbolEnum.BRACKET_LEFT.equals(firstCode.getSymbol())){
				result1=parseChildCode(firstCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
			}else if(FovasalaSymbolEnum.METHOD.equals(firstCode.getSymbol())){
				result1=invokeMethodByValidatePath((String)firstCode.getCode(), firstCode.getMethodArgs(), validateEntity, varMap, level, expression, codeRow);
			}else{
				result1=getValueByValidatePath(firstCode.getCode(), firstCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
			}
			FovasalaCode symbolCode=fovasalaCodeList.get(1);
			FovasalaCode lastCode=fovasalaCodeList.get(2);
			if(FovasalaSymbolEnum.BRACKET_LEFT.equals(lastCode.getSymbol())){
				result2=parseChildCode(lastCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
			}else if(FovasalaSymbolEnum.METHOD.equals(lastCode.getSymbol())){
				result2=invokeMethodByValidatePath((String)lastCode.getCode(), lastCode.getMethodArgs(), validateEntity, varMap, level, expression, codeRow);
			}else{
				result2=getValueByValidatePath(lastCode.getCode(), firstCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
			}
			if(FovasalaSymbolEnum.EQUAL.equals(symbolCode.getSymbol())){
				return ObjectUtils.equals(result1, result2, true);
			}else if(FovasalaSymbolEnum.NOT_EQUAL.equals(symbolCode.getSymbol())){
				return !ObjectUtils.equals(result1, result2, true);
			}else if(FovasalaSymbolEnum.GT.equals(symbolCode.getSymbol())){
				return ObjectUtils.isEmpty(result1) || ObjectUtils.isEmpty(result2)?false:(int)ClassUtils.invoke(result1, "compareTo", ObjectUtils.toArray(result1.getClass()), result2)>0;
			}else if(FovasalaSymbolEnum.GTE.equals(symbolCode.getSymbol())){
				return ObjectUtils.isEmpty(result1) || ObjectUtils.isEmpty(result2)?false:(int)ClassUtils.invoke(result1, "compareTo", ObjectUtils.toArray(result1.getClass()), result2)>=0;
			}else if(FovasalaSymbolEnum.LT.equals(symbolCode.getSymbol())){
				return ObjectUtils.isEmpty(result1) || ObjectUtils.isEmpty(result2)?false:(int)ClassUtils.invoke(result1, "compareTo", ObjectUtils.toArray(result1.getClass()), result2)<0;
			}else if(FovasalaSymbolEnum.LT.equals(symbolCode.getSymbol())){
				return ObjectUtils.isEmpty(result1) || ObjectUtils.isEmpty(result2)?false:(int)ClassUtils.invoke(result1, "compareTo", ObjectUtils.toArray(result1.getClass()), result2)<=0;
			}
			return false;
		}else{
			ExceptionUtils.trueException(fovasalaCodeList.size()!=1, "form.validate.syntax.error", String.format("无法进行表达式值转换，发生在行次：%s，代码：%s", codeRow, expression));
			FovasalaCode firstCode=fovasalaCodeList.get(0);
			Object result;
			if(FovasalaSymbolEnum.BRACKET_LEFT.equals(firstCode.getSymbol())){
				result=parseChildCode(firstCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
			}else if(FovasalaSymbolEnum.METHOD.equals(firstCode.getSymbol())){
				result=invokeMethodByValidatePath((String)firstCode.getCode(), firstCode.getMethodArgs(), validateEntity, varMap, level, expression, codeRow);
			}else{
				result=getValueByValidatePath(firstCode.getCode(), firstCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
			}
			return (boolean)result;
		}
	}
	
	@ApiMethod(value="如果是函数，则计算函数参数的值", params={@ApiField("表单验证实体"), @ApiField("临时变量"), @ApiField("代码层级"), @ApiField("代码行次"), @ApiField("行代码"), @ApiField("拆分后的代码列表对象")})
	private void joinBracketFunction(ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, int codeRow, String expression, List<FovasalaCode> fovasalaCodeList){
		if(!fovasalaCodeList.stream().filter(f -> FovasalaSymbolEnum.BRACKET_LEFT.equals(f.getSymbol())).findAny().isPresent()){//不存在则退出
			return ;
		}
		int length=fovasalaCodeList.size();
		FovasalaCode fovasalaCode, beforeCode=null;
		for(int i=0; i<length; i++){
			fovasalaCode = fovasalaCodeList.get(i);
			if(FovasalaSymbolEnum.BRACKET_LEFT.equals(fovasalaCode.getSymbol()) && ObjectUtils.isNotEmpty(beforeCode) && ObjectUtils.isEmpty(beforeCode.getSymbol())){
				List<FovasalaCode> childCodeList=fovasalaCode.getChildCodeList();
				List<Object> methodParamList=new ArrayList<Object>();
				if(ObjectUtils.isNotEmpty(childCodeList)){
					for (FovasalaCode childCode : childCodeList) {
						if(FovasalaSymbolEnum.METHOD_MULTI_PARAMETER.equals(childCode.getSymbol())){//多参数
							continue;
						}
						methodParamList.add(parseChildCode(ObjectUtils.asList(childCode), validateEntity, varMap, level, codeRow, expression));
					}
				}
				beforeCode.setMethodArgs(methodParamList.toArray());
				beforeCode.setSymbol(FovasalaSymbolEnum.METHOD);
				fovasalaCodeList.remove(i);
				i--;
				length--;
			}
			beforeCode=fovasalaCode;
		}
	}
	
	@ApiMethod(value="计算非(如：!aaa)", params={@ApiField("表单验证实体"), @ApiField("临时变量"), @ApiField("代码层级"), @ApiField("代码行次"), @ApiField("行代码"), @ApiField("拆分后的代码列表对象")})
	private void firstCalcBeNot(ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, int codeRow, String expression, List<FovasalaCode> fovasalaCodeList) {
		if(!fovasalaCodeList.stream().filter(f -> FovasalaSymbolEnum.BE_NOT.equals(f.getSymbol())).findAny().isPresent()){//不存在则退出
			return ;
		}
		Object beNot=null;//非的变量
		FovasalaCode fovasalaCode, beNotCode;//当前代码、非的变量代码
		int length=fovasalaCodeList.size();
		//从左往右先算除法
		for (int i = 0; i < length; i++) {
			fovasalaCode = fovasalaCodeList.get(i);
			if(ObjectUtils.isNotEmpty(fovasalaCode.getSymbol()) && FovasalaSymbolEnum.BE_NOT.equals(fovasalaCode.getSymbol())){
				beNotCode=fovasalaCodeList.get(i+1);
				if(FovasalaSymbolEnum.METHOD.equals(beNotCode.getSymbol())) {
					beNot=invokeMethodByValidatePath((String)beNotCode.getCode(), beNotCode.getMethodArgs(), validateEntity, varMap, level, expression, codeRow);
				}else if(ObjectUtils.isNotEmpty(beNotCode.getSymbol())){
					if(FovasalaSymbolEnum.BRACKET_LEFT.equals(beNotCode.getSymbol())){
						beNot=parseChildCode(beNotCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
					}else{
						throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", beNotCode.getSymbol().getSymbol(), codeRow, expression));
					}
				}else{
					beNot=getValueByValidatePath(beNotCode.getCode(), beNotCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
				}
				ExceptionUtils.trueException(ObjectUtils.isEmpty(beNot) || !(beNot instanceof Boolean), "form.validate.syntax.error", String.format("!的变量必须为boolean类型，发生在行次：%s，代码：%s", codeRow, expression));
				fovasalaCodeList.remove(i+1);
				fovasalaCodeList.remove(i);
				if(i==fovasalaCodeList.size()){
					fovasalaCodeList.add(new FovasalaCode(null, !(boolean)beNot));
				}else{
					fovasalaCodeList.add(i, new FovasalaCode(null, !(boolean)beNot));
				}
				length=fovasalaCodeList.size();
			}
		}
	}

	@ApiMethod(value="有++的先算++", params={@ApiField("表单验证实体"), @ApiField("临时变量"), @ApiField("代码层级"), @ApiField("代码行次"), @ApiField("行代码"), @ApiField("拆分后的代码列表对象")})
	private void firstCalcAddAdd(ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, int codeRow, String expression, List<FovasalaCode> fovasalaCodeList) {
		if(!fovasalaCodeList.stream().filter(f -> FovasalaSymbolEnum.ADD_ONE.equals(f.getSymbol())).findAny().isPresent()){//不存在则退出
			return ;
		}
		ExceptionUtils.trueException(fovasalaCodeList.size()!=2, "form.validate.syntax.error", String.format("x++或++x必须使用()，发生在行次：%s，代码：%s", codeRow, expression));
		FovasalaCode firstCode=fovasalaCodeList.get(0);
		FovasalaCode secondCode=fovasalaCodeList.get(1);
		Object result;
		if(FovasalaSymbolEnum.ADD_ONE.equals(firstCode.getSymbol())){
			if(ObjectUtils.isNotEmpty(secondCode.getSymbol())){
				if(FovasalaSymbolEnum.BRACKET_LEFT.equals(secondCode.getSymbol())){
					result=parseChildCode(secondCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
				}else{
					throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", secondCode.getSymbol().getSymbol(), codeRow, expression));
				}
			}else{
				result=getValueByValidatePath(secondCode.getCode(), secondCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
			}
			ExceptionUtils.trueException(NumberUtils.isDecimal(result, false), "form.validate.syntax.error", String.format("++号变量不能为空且必须是一个数字，发生在行次：%s，代码：%s", secondCode.getSymbol().getSymbol(), codeRow, expression));
			result=NumberUtils.add(result, 1);
			fovasalaCodeList.clear();
			fovasalaCodeList.add(new FovasalaCode(null, result));
		}else if(FovasalaSymbolEnum.ADD_ONE.equals(secondCode.getSymbol())){
			if(ObjectUtils.isNotEmpty(firstCode.getSymbol())){
				if(FovasalaSymbolEnum.BRACKET_LEFT.equals(firstCode.getSymbol())){
					result=parseChildCode(firstCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
				}else{
					throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", firstCode.getSymbol().getSymbol(), codeRow, expression));
				}
			}else{
				result=getValueByValidatePath(firstCode.getCode(), firstCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
			}
			ExceptionUtils.trueException(NumberUtils.isDecimal(result, false), "form.validate.syntax.error", String.format("++号变量不能为空且必须是一个数字，发生在行次：%s，代码：%s", firstCode.getSymbol().getSymbol(), codeRow, expression));
			Object addResult=NumberUtils.add(result, 1);
			fovasalaCodeList.clear();
			FovasalaCode newCode=new FovasalaCode(null, result);
			newCode.setNextCode(addResult);
			fovasalaCodeList.add(newCode);
		}
	}
	
	@ApiMethod(value="有--的先算--", params={@ApiField("表单验证实体"), @ApiField("临时变量"), @ApiField("代码层级"), @ApiField("代码行次"), @ApiField("行代码"), @ApiField("拆分后的代码列表对象")})
	private void firstCalcSubSub(ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, int codeRow, String expression, List<FovasalaCode> fovasalaCodeList) {
		if(!fovasalaCodeList.stream().filter(f -> FovasalaSymbolEnum.SUB_ONE.equals(f.getSymbol())).findAny().isPresent()){//不存在则退出
			return ;
		}
		ExceptionUtils.trueException(fovasalaCodeList.size()!=2, "form.validate.syntax.error", String.format("x++或++x必须使用()，发生在行次：%s，代码：%s", codeRow, expression));
		FovasalaCode firstCode=fovasalaCodeList.get(0);
		FovasalaCode secondCode=fovasalaCodeList.get(1);
		Object result;
		if(FovasalaSymbolEnum.SUB_ONE.equals(firstCode.getSymbol())){
			if(ObjectUtils.isNotEmpty(secondCode.getSymbol())){
				if(FovasalaSymbolEnum.BRACKET_LEFT.equals(secondCode.getSymbol())){
					result=parseChildCode(secondCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
				}else{
					throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", secondCode.getSymbol().getSymbol(), codeRow, expression));
				}
			}else{
				result=getValueByValidatePath(secondCode.getCode(), secondCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
			}
			ExceptionUtils.trueException(NumberUtils.isDecimal(result, false), "form.validate.syntax.error", String.format("++号变量不能为空且必须是一个数字，发生在行次：%s，代码：%s", secondCode.getSymbol().getSymbol(), codeRow, expression));
			result=NumberUtils.sub(result, 1);
			fovasalaCodeList.clear();
			fovasalaCodeList.add(new FovasalaCode(null, result));
		}else if(FovasalaSymbolEnum.SUB_ONE.equals(secondCode.getSymbol())){
			if(ObjectUtils.isNotEmpty(firstCode.getSymbol())){
				if(FovasalaSymbolEnum.BRACKET_LEFT.equals(firstCode.getSymbol())){
					result=parseChildCode(firstCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
				}else{
					throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", firstCode.getSymbol().getSymbol(), codeRow, expression));
				}
			}else{
				result=getValueByValidatePath(firstCode.getCode(), firstCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
			}
			ExceptionUtils.trueException(NumberUtils.isDecimal(result, false), "form.validate.syntax.error", String.format("++号变量不能为空且必须是一个数字，发生在行次：%s，代码：%s", firstCode.getSymbol().getSymbol(), codeRow, expression));
			Object addResult=NumberUtils.sub(result, 1);
			fovasalaCodeList.clear();
			FovasalaCode newCode=new FovasalaCode(null, result);
			newCode.setNextCode(addResult);
			fovasalaCodeList.add(newCode);
		}
	}
	
	@ApiMethod(value="有除法的优先算除法", params={@ApiField("表单验证实体"), @ApiField("临时变量"), @ApiField("代码层级"), @ApiField("代码行次"), @ApiField("行代码"), @ApiField("拆分后的代码列表对象")})
	private void firstCalcDivide(ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, int codeRow, String expression, List<FovasalaCode> fovasalaCodeList) {
		if(!fovasalaCodeList.stream().filter(f -> FovasalaSymbolEnum.DIV.equals(f.getSymbol())).findAny().isPresent()){//不存在则退出
			return ;
		}
		Object denominator=null, molecule=null;//分母、分子
		FovasalaCode fovasalaCode, denominatorCode, moleculeCode;//当前代码、分母、分子
		int length=fovasalaCodeList.size();
		//从左往右先算除法
		for (int i = 1; i < length; i++) {
			fovasalaCode = fovasalaCodeList.get(i);
			if(FovasalaSymbolEnum.DIV.equals(fovasalaCode.getSymbol())){
				denominatorCode=fovasalaCodeList.get(i+1);
				if(ObjectUtils.isNotEmpty(denominatorCode.getSymbol())){
					if(FovasalaSymbolEnum.BRACKET_LEFT.equals(denominatorCode.getSymbol())){
						denominator=parseChildCode(denominatorCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
					}else{
						throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", denominatorCode.getSymbol().getSymbol(), codeRow, expression));
					}
				}else{
					denominator=getValueByValidatePath(denominatorCode.getCode(), denominatorCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
				}
				moleculeCode=fovasalaCodeList.get(i-1);
				if(ObjectUtils.isNotEmpty(moleculeCode.getSymbol())){
					if(FovasalaSymbolEnum.BRACKET_LEFT.equals(moleculeCode.getSymbol())){
						molecule=parseChildCode(moleculeCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
					}else{
						throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", denominatorCode.getSymbol().getSymbol(), codeRow, expression));
					}
				}else{
					molecule=getValueByValidatePath(moleculeCode.getCode(), moleculeCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
				}
				ExceptionUtils.trueException(NumberUtils.isDecimal(denominator, false), "form.validate.syntax.error", String.format("‘/’号分母不能为空且必须是一个数字，发生在行次：%s，代码：%s", denominatorCode.getSymbol().getSymbol(), codeRow, expression));
				ExceptionUtils.trueException(new BigDecimal(denominator.toString()).compareTo(BigDecimal.ZERO)==0, "form.validate.syntax.error", String.format("‘/’号分母不能为0，发生在行次：%s，代码：%s", denominatorCode.getSymbol().getSymbol(), codeRow, expression));
				ExceptionUtils.trueException(NumberUtils.isDecimal(molecule, false), "form.validate.syntax.error", String.format("‘/’号分子不能为空且必须是一个数字，发生在行次：%s，代码：%s", denominatorCode.getSymbol().getSymbol(), codeRow, expression));
				fovasalaCodeList.remove(i+1);
				fovasalaCodeList.remove(i);
				fovasalaCodeList.remove(i-1);
				if(i==fovasalaCodeList.size()-1){
					fovasalaCodeList.add(new FovasalaCode(null, NumberUtils.divide(molecule, denominator, validateEntity.getConfig(ValidateConfigEnum.OPERATIONAL_SCALE.getKey()), validateEntity.getConfig(ValidateConfigEnum.OPERATIONAL_ROUNDING_MODE.getKey()))));
				}else{
					fovasalaCodeList.add(i-1, new FovasalaCode(null, NumberUtils.divide(molecule, denominator, validateEntity.getConfig(ValidateConfigEnum.OPERATIONAL_SCALE.getKey()), validateEntity.getConfig(ValidateConfigEnum.OPERATIONAL_ROUNDING_MODE.getKey()))));
				}
				i--;
				length=fovasalaCodeList.size();
			}
		}
	}
	
	@ApiMethod(value="算完除法之后算乘法", params={@ApiField("表单验证实体"), @ApiField("临时变量"), @ApiField("代码层级"), @ApiField("代码行次"), @ApiField("行代码"), @ApiField("拆分后的代码列表对象")})
	private void secondlyCalcMultiply(ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, int codeRow, String expression, List<FovasalaCode> fovasalaCodeList){
		if(!fovasalaCodeList.stream().filter(f -> FovasalaSymbolEnum.MUL.equals(f.getSymbol())).findAny().isPresent()){//不存在则退出
			return ;
		}
		Object multiplicand=null, multiplier=null;//被乘数、乘数
		FovasalaCode fovasalaCode, multiplicandCode, multiplierCode;//当前代码、被乘数、乘数
		int length=fovasalaCodeList.size();
		//从左往右算乘法
		for (int i = 1; i < length-1; i++) {
			fovasalaCode = fovasalaCodeList.get(i);
			if(FovasalaSymbolEnum.MUL.equals(fovasalaCode.getSymbol())){
				multiplierCode=fovasalaCodeList.get(i+1);
				if(ObjectUtils.isNotEmpty(multiplierCode.getSymbol())){
					if(FovasalaSymbolEnum.BRACKET_LEFT.equals(multiplierCode.getSymbol())){
						multiplier=parseChildCode(multiplierCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
					}else{
						throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", multiplierCode.getSymbol().getSymbol(), codeRow, expression));
					}
				}else{
					multiplier=getValueByValidatePath(multiplierCode.getCode(), multiplierCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
				}
				multiplicandCode=fovasalaCodeList.get(i-1);
				if(ObjectUtils.isNotEmpty(multiplicandCode.getSymbol())){
					if(FovasalaSymbolEnum.BRACKET_LEFT.equals(multiplicandCode.getSymbol())){
						multiplicand=parseChildCode(multiplicandCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
					}else{
						throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", multiplicandCode.getSymbol().getSymbol(), codeRow, expression));
					}
				}else{
					multiplicand=getValueByValidatePath(multiplicandCode.getCode(), multiplicandCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
				}
				ExceptionUtils.trueException(NumberUtils.isDecimal(multiplier, false), "form.validate.syntax.error", String.format("‘*’号分母不能为空且必须是一个数字，发生在行次：%s，代码：%s", multiplierCode.getSymbol().getSymbol(), codeRow, expression));
				ExceptionUtils.trueException(NumberUtils.isDecimal(multiplicand, false), "form.validate.syntax.error", String.format("‘*’号分子不能为空且必须是一个数字，发生在行次：%s，代码：%s", multiplicandCode.getSymbol().getSymbol(), codeRow, expression));
				fovasalaCodeList.remove(i+1);
				fovasalaCodeList.remove(i);
				fovasalaCodeList.remove(i-1);
				if(i==fovasalaCodeList.size()-1){
					fovasalaCodeList.add(new FovasalaCode(null, NumberUtils.multiply(multiplicand, multiplier, validateEntity.getConfig(ValidateConfigEnum.OPERATIONAL_SCALE.getKey()), validateEntity.getConfig(ValidateConfigEnum.OPERATIONAL_ROUNDING_MODE.getKey()))));
				}else{
					fovasalaCodeList.add(i-1, new FovasalaCode(null, NumberUtils.multiply(multiplicand, multiplier, validateEntity.getConfig(ValidateConfigEnum.OPERATIONAL_SCALE.getKey()), validateEntity.getConfig(ValidateConfigEnum.OPERATIONAL_ROUNDING_MODE.getKey()))));
				}
				i--;
				length=fovasalaCodeList.size();
			}
		}
	}
	
	@ApiMethod(value="算完除法、乘法之后算加减法", params={@ApiField("表单验证实体"), @ApiField("临时变量"), @ApiField("代码层级"), @ApiField("代码行次"), @ApiField("行代码"), @ApiField("拆分后的代码列表对象")})
	private void secondlyCalcAddSub(ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, int codeRow, String expression, List<FovasalaCode> fovasalaCodeList){
		if(fovasalaCodeList.stream().filter(f -> FovasalaSymbolEnum.SUB.equals(f.getSymbol())).findAny().isPresent()){//不存在则退出
			Object sub1=null, sub2=null;//被乘数、乘数
			FovasalaCode fovasalaCode, sub2Code, sub1Code;//当前代码、被乘数、乘数
			int length=fovasalaCodeList.size();
			//从左往右算乘法
			for (int i = 1; i < length-1; i++) {
				fovasalaCode = fovasalaCodeList.get(i);
				if(FovasalaSymbolEnum.SUB.equals(fovasalaCode.getSymbol())){
					sub1Code=fovasalaCodeList.get(i+1);
					if(ObjectUtils.isNotEmpty(sub1Code.getSymbol())){
						if(FovasalaSymbolEnum.BRACKET_LEFT.equals(sub1Code.getSymbol())){
							sub1=parseChildCode(sub1Code.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
						}else{
							throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", sub1Code.getSymbol().getSymbol(), codeRow, expression));
						}
					}else{
						sub1=getValueByValidatePath(sub1Code.getCode(), sub1Code.getSymbol(), validateEntity, varMap, level, expression, codeRow);
					}
					sub2Code=fovasalaCodeList.get(i-1);
					if(ObjectUtils.isNotEmpty(sub2Code.getSymbol())){
						if(FovasalaSymbolEnum.BRACKET_LEFT.equals(sub2Code.getSymbol())){
							sub2=parseChildCode(sub2Code.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
						}else{
							throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", sub2Code.getSymbol().getSymbol(), codeRow, expression));
						}
					}else{
						sub2=getValueByValidatePath(sub2Code.getCode(), sub2Code.getSymbol(), validateEntity, varMap, level, expression, codeRow);
					}
					ExceptionUtils.trueException(NumberUtils.isDecimal(sub1, false), "form.validate.syntax.error", String.format("‘-’号分母不能为空且必须是一个数字，发生在行次：%s，代码：%s", sub1Code.getSymbol().getSymbol(), codeRow, expression));
					ExceptionUtils.trueException(NumberUtils.isDecimal(sub1, false), "form.validate.syntax.error", String.format("‘-’号分子不能为空且必须是一个数字，发生在行次：%s，代码：%s", sub2Code.getSymbol().getSymbol(), codeRow, expression));
					fovasalaCodeList.remove(i+1);
					fovasalaCodeList.remove(i);
					fovasalaCodeList.remove(i-1);
					if(i==fovasalaCodeList.size()-1){
						fovasalaCodeList.add(new FovasalaCode(null, NumberUtils.sub(sub2, sub1)));
					}else{
						fovasalaCodeList.add(i-1, new FovasalaCode(null, NumberUtils.sub(sub2, sub1)));
					}
					i--;
					length=fovasalaCodeList.size();
				}
			}
		}
		if(fovasalaCodeList.stream().filter(f -> FovasalaSymbolEnum.ADD.equals(f.getSymbol())).findAny().isPresent()){//不存在则退出
			Object add1=null, add2=null;//被乘数、乘数
			FovasalaCode fovasalaCode, add2Code, add1Code;//当前代码、被乘数、乘数
			int length=fovasalaCodeList.size();
			//从左往右算乘法
			for (int i = 1; i < length-1; i++) {
				fovasalaCode = fovasalaCodeList.get(i);
				if(FovasalaSymbolEnum.ADD.equals(fovasalaCode.getSymbol())){
					add1Code=fovasalaCodeList.get(i+1);
					if(ObjectUtils.isNotEmpty(add1Code.getSymbol())){
						if(FovasalaSymbolEnum.BRACKET_LEFT.equals(add1Code.getSymbol())){
							add1=parseChildCode(add1Code.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
						}else{
							throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", add1Code.getSymbol().getSymbol(), codeRow, expression));
						}
					}else{
						add1=getValueByValidatePath(add1Code.getCode(), add1Code.getSymbol(), validateEntity, varMap, level, expression, codeRow);
					}
					add2Code=fovasalaCodeList.get(i-1);
					if(ObjectUtils.isNotEmpty(add2Code.getSymbol())){
						if(FovasalaSymbolEnum.BRACKET_LEFT.equals(add2Code.getSymbol())){
							add2=parseChildCode(add2Code.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
						}else{
							throw ExceptionUtils.message("form.validate.syntax.error", String.format("发生在字符‘%s’附近，发生在行次：%s，代码：%s", add2Code.getSymbol().getSymbol(), codeRow, expression));
						}
					}else{
						add2=getValueByValidatePath(add2Code.getCode(), add2Code.getSymbol(), validateEntity, varMap, level, expression, codeRow);
					}
					ExceptionUtils.trueException(NumberUtils.isDecimal(add1, false), "form.validate.syntax.error", String.format("‘-’号分母不能为空且必须是一个数字，发生在行次：%s，代码：%s", add1Code.getSymbol().getSymbol(), codeRow, expression));
					ExceptionUtils.trueException(NumberUtils.isDecimal(add2, false), "form.validate.syntax.error", String.format("‘-’号分子不能为空且必须是一个数字，发生在行次：%s，代码：%s", add2Code.getSymbol().getSymbol(), codeRow, expression));
					fovasalaCodeList.remove(i+1);
					fovasalaCodeList.remove(i);
					fovasalaCodeList.remove(i-1);
					if(i==fovasalaCodeList.size()-1){
						fovasalaCodeList.add(new FovasalaCode(null, NumberUtils.add(add2, add1)));
					}else{
						fovasalaCodeList.add(i-1, new FovasalaCode(null, NumberUtils.add(add2, add1)));
					}
					i--;
					length=fovasalaCodeList.size();
				}
			}
		}
	}
	
	private Object parseChildCode(List<FovasalaCode> childCodeList, ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, int codeRow, String expression){
		firstCalcAddAdd(validateEntity, varMap, level, codeRow, expression, childCodeList);//++
		firstCalcSubSub(validateEntity, varMap, level, codeRow, expression, childCodeList);//++
		firstCalcDivide(validateEntity, varMap, level, codeRow, expression, childCodeList);//先算除法
		secondlyCalcMultiply(validateEntity, varMap, level, codeRow, expression, childCodeList);//再算乘法
		secondlyCalcAddSub(validateEntity, varMap, level, codeRow, expression, childCodeList);//再算加、减法
		joinBracketFunction(validateEntity, varMap, level, codeRow, expression, childCodeList);//把函数拼接起来
		firstCalcBeNot(validateEntity, varMap, level, codeRow, expression, childCodeList);//再算非
		
		if(childCodeList.stream().filter(f -> ObjectUtils.isNotEmpty(f.getSymbol()) && 
				ObjectUtils.containsOnce(f.getSymbol().getSymbol(), FovasalaSymbolEnum.EQUAL.getSymbol(), FovasalaSymbolEnum.NOT_EQUAL.getSymbol(), 
						FovasalaSymbolEnum.GT.getSymbol(), FovasalaSymbolEnum.GTE.getSymbol(),
						FovasalaSymbolEnum.LT.getSymbol(), FovasalaSymbolEnum.LTE.getSymbol()
		)).findAny().isPresent()){//aaa=bbb
			FovasalaCode firstCode=childCodeList.get(0);
			ExceptionUtils.trueException(childCodeList.size()!=3, "form.validate.syntax.error", String.format("无法进行表达式比较，发生在行次：%s，代码：%s", codeRow, expression));
			Object result1,result2;
			firstCode=childCodeList.get(0);
			if(FovasalaSymbolEnum.BRACKET_LEFT.equals(firstCode.getSymbol())){
				result1=parseChildCode(firstCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
			}else if(FovasalaSymbolEnum.METHOD.equals(firstCode.getSymbol())){
				result1=invokeMethodByValidatePath((String)firstCode.getCode(), firstCode.getMethodArgs(), validateEntity, varMap, level, expression, codeRow);
			}else{
				result1=getValueByValidatePath(firstCode.getCode(), firstCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
			}
			FovasalaCode symbolCode=childCodeList.get(1);
			FovasalaCode lastCode=childCodeList.get(2);
			if(FovasalaSymbolEnum.BRACKET_LEFT.equals(lastCode.getSymbol())){
				result2=parseChildCode(lastCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
			}else if(FovasalaSymbolEnum.METHOD.equals(firstCode.getSymbol())){
				result2=invokeMethodByValidatePath((String)firstCode.getCode(), firstCode.getMethodArgs(), validateEntity, varMap, level, expression, codeRow);
			}else{
				result2=getValueByValidatePath(lastCode.getCode(), lastCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
			}
			if(FovasalaSymbolEnum.EQUAL.equals(symbolCode.getSymbol())){
				return ObjectUtils.equals(result1, result2, true);
			}else if(FovasalaSymbolEnum.NOT_EQUAL.equals(symbolCode.getSymbol())){
				return !ObjectUtils.equals(result1, result2, true);
			}else if(FovasalaSymbolEnum.GT.equals(symbolCode.getSymbol())){
				return ObjectUtils.isEmpty(result1) || ObjectUtils.isEmpty(result2)?false:(int)ClassUtils.invoke(result1, "compareTo", ObjectUtils.toArray(result1.getClass()), result2)>0;
			}else if(FovasalaSymbolEnum.GTE.equals(symbolCode.getSymbol())){
				return ObjectUtils.isEmpty(result1) || ObjectUtils.isEmpty(result2)?false:(int)ClassUtils.invoke(result1, "compareTo", ObjectUtils.toArray(result1.getClass()), result2)>=0;
			}else if(FovasalaSymbolEnum.LT.equals(symbolCode.getSymbol())){
				return ObjectUtils.isEmpty(result1) || ObjectUtils.isEmpty(result2)?false:(int)ClassUtils.invoke(result1, "compareTo", ObjectUtils.toArray(result1.getClass()), result2)<0;
			}else if(FovasalaSymbolEnum.LT.equals(symbolCode.getSymbol())){
				return ObjectUtils.isEmpty(result1) || ObjectUtils.isEmpty(result2)?false:(int)ClassUtils.invoke(result1, "compareTo", ObjectUtils.toArray(result1.getClass()), result2)<=0;
			}
			return false;
		}else{
			ExceptionUtils.trueException(childCodeList.size()!=1, "form.validate.syntax.error", String.format("无法进行表达式值转换，发生在行次：%s，代码：%s", codeRow, expression));
			FovasalaCode firstCode=childCodeList.get(0);
			Object result;
			if(FovasalaSymbolEnum.BRACKET_LEFT.equals(firstCode.getSymbol())){
				result=parseChildCode(firstCode.getChildCodeList(), validateEntity, varMap, level, codeRow, expression);
			}else if(FovasalaSymbolEnum.METHOD.equals(firstCode.getSymbol())){
				result=invokeMethodByValidatePath((String)firstCode.getCode(), firstCode.getMethodArgs(), validateEntity, varMap, level, expression, codeRow);
			}else{
				result=getValueByValidatePath(firstCode.getCode(), firstCode.getSymbol(), validateEntity, varMap, level, expression, codeRow);
			}
			return result;
		}
	}
	
	@ApiMethod(value="设置变量", params={@ApiField("表单验证表达式"), @ApiField("表单验证对象"), @ApiField("临时变量Map"), @ApiField("表单验证关键词枚举"), @ApiField("代码层级"), @ApiField("代码行")})
	private void setVar(String expression, ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, KeywordEnum statement, int level, int codeRow){
		ExceptionUtils.empty(expression, "field.empty", "表单验证代码");
		if(KeywordEnum.KEYWORD_FOREACH.equals(statement)){
			expression=expression.replace("  ", " ").trim();
			ExceptionUtils.trueException(!expression.matches(statement.getStatementRegexp()), "form.validate.syntax.error", String.format("‘foreach’语句代码应符合格式‘var [var] as [collect]’，发生在行次：%s，代码：%s", codeRow, expression));
			String[] itemArray=expression.split(" ");
			String listDefine=itemArray[3];
			Object foreachList = getValueByValidatePath(listDefine, null, validateEntity, varMap, level, expression, codeRow);
			Map<String, Object> levelVarMap=new HashMap<String, Object>();
			levelVarMap.put("foreachVar", itemArray[1]);
			if(ObjectUtils.isEmpty(foreachList)){
				levelVarMap.put("foreachList", foreachList);
				levelVarMap.put("foreachLength", 0);
				levelVarMap.put(itemArray[1], null);
				levelVarMap.put(itemArray[1]+"Index", 0);
			}else{
				if(foreachList.getClass().isArray()){//foreach循环列表为数组
					levelVarMap.put("foreachList", foreachList);
					levelVarMap.put("foreachLength", Array.getLength(foreachList));
					levelVarMap.put(itemArray[1]+"Index", 0);
				}else if(foreachList instanceof List){//foreach循环列表为List
					levelVarMap.put("foreachList", foreachList);
					levelVarMap.put("foreachLength", ((List<?>)foreachList).size());
					levelVarMap.put(itemArray[1]+"Index", 0);
				}else if(foreachList instanceof Collection){//foreach循环列表为Collection
					int length=((Collection<?>)foreachList).size();
					foreachList=((Collection<?>)foreachList).iterator();
					levelVarMap.put("foreachList", foreachList);
					levelVarMap.put("foreachLength", length);
					levelVarMap.put(itemArray[1]+"Index", 0);
				}else if(foreachList instanceof Map){//foreach循环列表为Map
					int length=((Map<?,?>)foreachList).size();
					foreachList=((Map<?,?>)foreachList).entrySet().iterator();
					levelVarMap.put("foreachList", foreachList);
					levelVarMap.put("foreachLength", length);
					levelVarMap.put(itemArray[1]+"Index", 0);
				}else{
					throw ExceptionUtils.message("form.validate.syntax.error", String.format("foreach语句列表对象类型为：%s，尚未实现，请联系技术人员", foreachList.getClass().getName()));
				}
				levelVarMap.put(itemArray[1], updateForeach(foreachList, 0));
				
			}
			varMap.put(level, levelVarMap);//设置变量
		}else if(KeywordEnum.KEYWORD_VAR.equals(statement) || KeywordEnum.KEYWORD_VALUE.equals(statement)){
			expression=expression.replace(" ", "");
			int split=expression.indexOf("=");
			if(split!=-1){
				String varName=expression.substring(0, split);
				String valuePath=expression.substring(split+1);
				List<FovasalaCode> fovasalaCodeList=fovasalaCodeParse.parse(valuePath);
				Object value = parseChildCode(fovasalaCodeList, validateEntity, varMap, level, codeRow, expression);
				Map<String, Object> levelVarMap=varMap.get(level);
				if(ObjectUtils.isEmpty(levelVarMap)){
					levelVarMap=new HashMap<String, Object>();
					varMap.put(level, levelVarMap);
				}
				levelVarMap.put(varName, value);
			}else{
				List<FovasalaCode> fovasalaCodeList=fovasalaCodeParse.parse(expression);
				ExceptionUtils.trueException(fovasalaCodeList.size()!=2, "form.validate.syntax.error", String.format("必须符合++a,--a,a++,a--规范，发生在行次：%s，代码：%s", codeRow, expression));
				FovasalaCode firstCode=fovasalaCodeList.get(0);
				String varName;
				if(ObjectUtils.isNotEmpty(firstCode.getSymbol())){
					if(FovasalaSymbolEnum.ADD_ONE.equals(firstCode.getSymbol()) || FovasalaSymbolEnum.SUB_ONE.equals(firstCode.getSymbol())){
						varName=(String)fovasalaCodeList.get(1).getCode();
					}else{
						throw ExceptionUtils.message("form.validate.syntax.error", String.format("无法识别的符号‘%s’，发生在行次：%s，代码：%s", firstCode.getSymbol().getSymbol(),codeRow, expression));
					}
				}else{
					FovasalaCode secondCode=fovasalaCodeList.get(1);
					if(FovasalaSymbolEnum.ADD_ONE.equals(secondCode.getSymbol()) || FovasalaSymbolEnum.SUB_ONE.equals(secondCode.getSymbol())){
						varName=(String)firstCode.getCode();
					}else{
						throw ExceptionUtils.message("form.validate.syntax.error", String.format("无法识别的符号‘%s’，发生在行次：%s，代码：%s", firstCode.getSymbol().getSymbol(),codeRow, expression));
					}
				}
				Object value = parseChildCode(fovasalaCodeList, validateEntity, varMap, level, codeRow, expression);
				Map<String, Object> levelVarMap=varMap.get(level);
				if(ObjectUtils.isEmpty(levelVarMap)){
					levelVarMap=new HashMap<String, Object>();
					varMap.put(level, levelVarMap);
				}
				levelVarMap.put(varName, value);
			}
		}else{
			throw ExceptionUtils.message("form.validate.syntax.error", String.format("%s尚不支持变量设置", statement.getKeyword()));
		}
	}
	
	private Object updateForeach(Object foreachList, int index){
		if(foreachList.getClass().isArray()){//foreach循环列表为数组
			return Array.get(foreachList, index);
		}else if(foreachList instanceof List){//foreach循环列表为List
			return ((List<?>)foreachList).get(index);
		}else if(foreachList instanceof Iterator){//foreach循环列表为Collection
			return ((Iterator<?>)foreachList).next();
		}else{
			throw ExceptionUtils.message("form.validate.syntax.error", String.format("foreach语句列表对象类型为：%s，尚未实现，请联系技术人员", foreachList.getClass().getName()));
		}
	}
	
	@ApiMethod(value="根据表单验证Path执行方法", params={@ApiField("方法path"), @ApiField("方法参数"), @ApiField("表单验证对象"), @ApiField("临时变量"), @ApiField("代码层级"), @ApiField("行表达式"), @ApiField("代码行次")})
	private Object invokeMethodByValidatePath(String valuePathObj, Object[] methodArgs, ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, String expression, int codeRow){
		int last=valuePathObj.lastIndexOf(".");
		ExceptionUtils.trueException(last==-1, "form.validate.syntax.error", String.format("无法执行方法‘%s’，发生在行次：%s，代码：%s", valuePathObj, codeRow, expression));
		Object source=getValueByValidatePath(valuePathObj.subSequence(0, last), null, validateEntity, varMap, level, expression, codeRow);
		String methodName=valuePathObj.substring(last+1);
		return ClassUtils.invoke(source, methodName, new HashMap<Integer, Class<?>>(), methodArgs);
	}

	@ApiMethod(value="根据表单验证Path取值，如：aaa.bbb.ccc,优先在varMap中取值，否则在validateEntity中取值", params={@ApiField("值path"), @ApiField("表单验证对象"), @ApiField("临时变量"), @ApiField("代码层级"), @ApiField("行表达式"), @ApiField("代码行次")})
	private Object getValueByValidatePath(Object valuePathObj, FovasalaSymbolEnum symbol, ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, String expression, int codeRow) {
		if(!(valuePathObj instanceof String)){
			return valuePathObj;
		}
		String valuePath=valuePathObj.toString();
		if(valuePath.equals("true")){
			return true;
		}else if(valuePath.equals("false")){
			return false;
		}else if(valuePath.matches("^[0-9\\-]+$")){
			if(valuePath.length()>9) {
				return Long.parseLong(valuePath);
			}else {
				return Integer.parseInt(valuePath);
			}
		}else if(valuePath.matches("^[0-9.\\-]+L$")){
			return Long.parseLong(valuePath);
		}else if(valuePath.matches("^[0-9.\\-]+$")){
			return new BigDecimal(valuePath);
		}else if(valuePath.matches("^'[^']+'$")){
			return valuePath.substring(1, valuePath.length()-1);
		}else if(valuePath.matches("^\"[^\"]+\"$")){
			return valuePath.substring(1, valuePath.length()-1);
		}else if(FovasalaSymbolEnum.STRING.equals(symbol) || FovasalaSymbolEnum.STRING2.equals(symbol)) {
			return valuePath;
		}
		int first=valuePath.indexOf(".");
		String lastListDefine=null;
		if(first!=-1){
			lastListDefine=valuePath.substring(first+1);
			valuePath=valuePath.substring(0, first);
		}
		Object value=getCodeRootValue(valuePath, validateEntity, varMap, level, expression, codeRow);
		if(ObjectUtils.isNotEmpty(lastListDefine)){
			value=ClassUtils.getPathField(value, lastListDefine).getFieldValue();
		}
		return value;
	}
	
	@ApiMethod(value="表单验证中根据代码确定跟对象的值，如：entity.xxx，表示取自validateEntity中的entity对象，再如：session.getAttribute(xxx)，表示取自validateEntity中的session对象", params={@ApiField("变量代码"), @ApiField("表单验证对象"), @ApiField("临时变量Map"), @ApiField("取值代码层级"), @ApiField("行完整代码"), @ApiField("代码行次")})
	private Object getCodeRootValue(String code, ValidateEntity<?> validateEntity, Map<Integer, Map<String, Object>> varMap, int level, String rowCode, int codeRow){
		int first=code.indexOf("[");
		String arrayIndex=null;
		if(first!=-1){
			arrayIndex=code.substring(first);
			code=code.substring(0, first);
		}
		Map<String, Object> levelVarMap;
		Object codeValue=null;
		boolean match=false;
		for (int i = level; i > 0; i--) {//根据代码层级level，在变量Map中查找code表示的对象值，逻辑：凡是小于当前层级的变量Map都需要查找，直到找到一级，变量Map没有零级
			levelVarMap=varMap.get(i);
			if(ObjectUtils.isNotEmpty(levelVarMap) && levelVarMap.containsKey(code)){
				codeValue=levelVarMap.get(code);
				match=true;
				break;
			}
		}
		if(!match){//在表单验证对象中查找code表示的对象值
			if(code.equals("entity")){
				codeValue=validateEntity.getEntity();
			}else if(code.equals("request")){
				codeValue=validateEntity.getRequest();
			}else if(code.equals("response")){
				codeValue=validateEntity.getResponse();
			}else if(code.equals("session")){
				codeValue=validateEntity.getSession();
			}else if(ObjectUtils.isNotEmpty(validateEntity.getAttribute()) && validateEntity.getAttribute().containsKey(code)){
				codeValue=validateEntity.getAttribute(code);
			}
		}
		if(ObjectUtils.isEmpty(codeValue)){
			return codeValue;
		}
		if(ObjectUtils.isNotEmpty(arrayIndex)){//code代码中存在[n]，则需要进行数组取值，如：[0][1]
			int arrayFirst=0, arrayLast=arrayIndex.indexOf("]"), arrayIndexItem;
			String item;
			ExceptionUtils.equals(arrayIndex, -1, "form.validate.syntax.error", String.format("未找到数组结束符‘]’，发生在行次：%s，代码：%s", codeRow, rowCode));
			while(true){
				item=ObjectUtils.init(arrayIndex.substring(arrayFirst+1, arrayLast), "0");
				ExceptionUtils.trueException(!item.matches("^[0-9]+$"), "form.validate.syntax.error", String.format("数组索引只能是数组，发生在行次：%s，代码：%s", codeRow, rowCode));
				arrayIndexItem=Integer.parseInt(item);
				if(codeValue.getClass().isArray()){
					codeValue=Array.get(codeValue, arrayIndexItem);
				}else if(codeValue instanceof List){
					codeValue=((List<?>)codeValue).get(arrayIndexItem);
				}else{
					throw ExceptionUtils.message("form.validate.syntax.error", String.format("对象非数组或列表，不能使用‘[n]’获取，当前对象类型“%s”，发生在行次：%s，代码：%s", codeValue.getClass().getName(), codeRow, rowCode));
				}
				if(ObjectUtils.isEmpty(codeValue)){
					break;
				}
				if(arrayLast==arrayIndex.length()-1){
					break;
				}
				arrayFirst=arrayIndex.indexOf("[", arrayLast);
				if(arrayFirst!=-1) {
					arrayFirst++;
				}
				arrayLast=arrayIndex.indexOf("]", arrayFirst);
			}
		}
		return codeValue;
	}
	
	@Override
	@ApiMethod(value="设置本次验证扩展参数，用户可调用非固定参数外的参数", params = {@ApiField("参数的名称"), @ApiField("参数的值")})
	public void setAttribute(String key, Object value) {
		attributeLocal.get().put(key, value);
	}
	
	@Override
	@SuppressWarnings("unchecked")
	@ApiMethod(value="获取本次验证扩展参数，可作为本线程缓存", params = {@ApiField("参数的名称")}, returns = @ApiField("参数的值"))
	public <T> T getAttribute(String key) {
		return (T)attributeLocal.get().get(key);
	}
	
	@Override
	@ApiMethod("验证结束时调用，若设置了扩展属性或者有缓存存在，则需执行此方法")
	public void finish() {
		attributeLocal.remove();//清理本线程验证缓存
	}
}
